/**
 * 基础配置
 */
const baseConf = {
    legend: {
        type: "scroll",
        left: 'center',
        bottom: 10,
    },

    dataZoom: {type: 'inside'},

    tooltip: {
        appendToBody: true,
        trigger: 'axis',
        axisPointer: {
            animation: false,
            lineStyle: {
                color: '#9B8466',
            },
        },
        textStyle: {
            color: '#fff',
            fontSize: 14,
        },
        backgroundColor: 'rgba(74,66,42,0.9)', // 背景颜色
        borderRadius: 10,
        borderColor: '#C2A175'
    },

    xAxis: {
        type: 'category'
    }
}


/**
 * 通用图表
 * @name top-chart
 */
Vue.component('top-chart', {
    template: `
        <div :id="uuid" :style="chartStyle"></div>
    `,

    props: {
        width: {type: [String, Number], default: ''}, // 图表width
        height: {type: [String, Number], default: ''}, // 图表height
        option: {type: Object, default: () => null}, // 图表配置项
        renderer: {type: String, default: 'svg'}, // 渲染模式
        animate: {type: Boolean, default: false}, // 是否开启动画
        seriesType: {type: String, default: 'line'}
    },

    data() {
        return {
            uuid: '', // 组件唯一标识
            myChart: null, // chart 对象
        };
    },

    computed: {
        // 图表容器的样式
        chartStyle() {
            let height = '100%';
            let width = '100%';
            if (this.height) {
                height = typeof this.height === 'number' ? this.height + 'px' : this.height;
            }
            return {
                height: height,
                width: width,
            };
        },
    },

    watch: {
        // 监听配置相关
        option: {
            handler(opt) {
                if (opt) {
                    try {
                        this.$nextTick(() => {
                            this.initEcharts();
                        });
                    } catch (e) {
                        console.warn('初始化图表失败，请检查', e.message);
                    }
                }
            },
            immediate: true,
            deep: true,
        },
    },

    methods: {
        /**
         * 初始化echart
         */
        initEcharts() {
            const dom = document.getElementById(this.uuid);
            if (!dom) return;
            if (this.myChart) this.myChart.clear();
            this.myChart = echarts.init(dom, 'theme');
            this.myChart.setOption(this.option);
            this.$emit({chart: this.myChart});
            this.myChart.on('click', (e) => {
                this.$emit('chart-click', e);
            });
            window.addEventListener('resize', () => {
                if (!this.myChart) return;
                this.myChart.resize();
            });

            this.$emit('loaded', this.myChart)

            if (this.animate) {
                if (this.seriesType === 'pie') {
                    const data = this.option.series[0].data;
                    tpUtils.pieChartAnimation(this.myChart, data, 0)
                }
            }
        },
    },

    created() {
        this.uuid = uuidGenerate();
    },
});

/**
 * 折线图
 * @name top-echart-line
 */
Vue.component('top-chart-line', {
    template: `
        <top-chart :option="lineOption" ref="topChartLine" v-if="lineOption" v-bind="$attrs" v-on="$listeners"></top-chart>   
    `,
    props: {
        option: {type: Object, default: () => null}, // 图表配置项
        animate: {type: Boolean, default: false},
    },

    data() {
        return {
            uuid: '', // 组件唯一标识
            myChart: null, // chart 对象
        };
    },

    computed: {
        lineOption() {
            if (!this.option) return null;
            let {name, grid, yAxis = {}, xAxis, xAxisData = [], series, seriesData, legendData = [], tooltip = {}, legend, visualMap, smooth = false} = this.option;

            /** 重写xAxis **/
            // 直接写xAxisData(单个X轴)
            if (!xAxis && xAxisData && isArray(xAxisData) && xAxisData.length) {
                xAxis = {...baseConf.xAxis, data: xAxisData};
            }

            // 重写xAxis
            if (xAxis) {
                if (isObject(xAxis)) {
                    xAxis = {...baseConf.xAxis, ...xAxis};
                }
                if (isArray(xAxis)) {
                    xAxis = xAxis.map((item) => {
                        return {...baseConf.xAxis, ...item};
                    });
                }
            }

            const yAxisBase = {type: 'value'}

            // 重写yAxis
            if (yAxis) {
                if (isObject(yAxis)) {
                    yAxis = {...yAxisBase, ...yAxis};
                }
                if (isArray(yAxis)) {
                    yAxis = yAxis.map((item) => {
                        return {...yAxisBase, ...item};
                    });
                }
            }

            // 重写series
            const baseSeries = {
                type: 'line',
                smooth: smooth,
                name: (name || '当前值'),
                lineStyle: {
                    normal: {
                        width: 1,
                    },
                },
                showSymbol: true,
                symbol: "circle",
                symbolSize: 3,
            };
            if (!series && seriesData && isArray(seriesData) && seriesData.length) {
                series = {
                    ...baseSeries,
                    data: seriesData,
                };
            }

            if (series) {
                if (isObject(series)) {
                    series = {...baseSeries, ...series};
                }
                if (isArray(series)) {
                    series = series.map((item) => {
                        return {
                            ...baseSeries,
                            ...item,
                        };
                    });
                }
            }

            return {
                ...this.option,
                yAxis: yAxis,
                xAxis: xAxis,
                series: series,
                grid: {...grid},
                dataZoom: {...baseConf.dataZoom},
                legend: {data: legendData, ...baseConf.legend, ...legend},
                tooltip: {...baseConf.tooltip, ...tooltip},
                visualMap: visualMap,
            };
        },
    },
});

/**
 * 饼图
 * @name top-echart-pie
 */
Vue.component('top-chart-pie', {
    template: `
        <top-chart :option="pieOption" v-if="pieOption" v-bind="$attrs" series-type="pie"></top-chart>   
    `,
    props: {
        option: {type: Object, default: () => null},            // 图表配置项
    },

    data() {
        return {
            uuid: '', // 组件唯一标识
            myChart: null, // chart 对象
        };
    },

    computed: {
        pieOption() {
            if (!this.option) return null;
            let {
                title,
                name,
                grid,
                series,
                seriesData,
                legendData = [],
                tooltip = {},
                legend,
            } = this.option;

            const baseSeriesOpt = {
                title,
                type: 'pie',
                name: 'seriesname',
                avoidLabelOverlap: false,
                label: {
                    show: false,
                    position: 'center',
                    color: '#3df1d1',
                    fontSize: 16,
                    fontWeight: 600,
                },

                radius: ['40%', '70%'],
                emphasis: {
                    label: {
                        show: true,
                        fontSize: 16,
                        fontWeight: 600,
                    },
                },
                labelLine: {
                    show: false,
                },
            };

            // 重写series
            if (!series && seriesData && isArray(seriesData) && seriesData.length) {
                series = {
                    ...baseSeriesOpt,
                    data: seriesData,
                    name: name,
                };
            }

            if (series) {
                if (isObject(series)) {
                    series = {
                        ...baseSeriesOpt,
                        ...series,
                    };
                }
                if (isArray(series)) {
                    series = series.map((item) => {
                        return {
                            ...baseSeriesOpt,
                            ...item,
                        };
                    });
                }
            }

            return {
                title,
                series: series,
                grid: {top: 10, left: 10, right: 10, bottom: 10, ...grid},
                legend: {
                    data: legendData,
                    textStyle: {fontSize: 10},

                    ...legend,
                },

                tooltip: {
                    trigger: 'axis',
                    textStyle: {fontSize: 10},
                    backgroundColor: 'rgba(0,0,0,0.76)',
                    borderColor: '#46ACEA',
                    appendToBody: true,
                    axisPointer: {
                        label: {
                            backgroundColor: '#6a7985',
                            color: '#fff',
                        },
                    },
                    ...tooltip,
                },
                ...this.options,
            };
        },
    },
});

/**
 * 柱状图
 * @name top-echart-bar
 */
Vue.component('top-chart-bar', {
    template: `
        <top-chart :option="barOption" v-if="barOption" v-bind="$attrs"></top-chart>   
    `,
    props: {
        option: {
            type: Object,
            default: () => {
                return {
                    name: '柱状图',
                };
            },
        }, // 图表配置项
        animate: {type: Boolean, default: false},
    },

    data() {
        return {
            uuid: '', // 组件唯一标识
            myChart: null, // chart 对象
        };
    },

    computed: {
        barOption() {
            if (!this.option) return null;
            let {
                name,
                grid,
                yAxis,
                yAxisData = [],
                xAxis,
                xAxisData = [],
                series,
                seriesData,
                legendData = [],
                tooltip = {},
                legend,
            } = this.option;
            const baseSeriesOpt = {type: 'bar', name: 'seriesname'};

            // 直接写xAxisData(单个X轴)
            if (!xAxis && xAxisData && isArray(xAxisData) && xAxisData.length) {
                xAxis = {type: 'category', data: xAxisData};
            }
            // 重写xAxis
            if (xAxis) {
                if (isObject(xAxis)) {
                    xAxis = {type: 'category', ...xAxis};
                }
                if (isArray(xAxis)) {
                    xAxis = xAxis.map((item) => {
                        return {type: 'category', ...item};
                    });
                }
            }

            // if (!yAxis && yAxisData && isArray(yAxisData) && yAxisData.length) {
            //     yAxis = {type: 'value'};
            //
            //     yAxis = {
            //             type: 'category',
            //             data: yAxisData,
            //             inverse: true,
            //
            //         }
            // }

            // 重写series
            if (!series && seriesData && isArray(seriesData) && seriesData.length) {
                series = {
                    ...baseSeriesOpt,
                    data: seriesData,
                    name: name,
                };
            }

            if (series) {
                if (isObject(series)) {
                    series = {
                        ...baseSeriesOpt,
                        ...series,
                    };
                }
                if (isArray(series)) {
                    series = series.map((item) => {
                        return {
                            ...baseSeriesOpt,
                            ...item,
                        };
                    });
                }
            }

            return {
                dataZoom: {type: 'inside'},
                ...this.option,
                // yAxis: yAxis,
                // xAxis: xAxis,
                // series: series,
                // grid: {top: 10, left: 10, right: 10, bottom: 10, ...grid},
                // legend: {
                //     data: legendData,
                //     textStyle: {fontSize: 10},
                //     ...legend,
                // },
                //
                // tooltip: {
                //     trigger: 'axis',
                //     textStyle: {fontSize: 10},
                //     backgroundColor: 'rgba(0,0,0,0.76)',
                //     borderColor: '#46ACEA',
                //     axisPointer: {
                //         label: {
                //             backgroundColor: '#6a7985',
                //             color: '#fff'
                //         }
                //     },
                //     ...tooltip
                // },
            };
        },
    },
});

/**
 * 混合图
 * @name top-echart-mixin
 */
Vue.component('top-chart-mixin', {
    template: `
        <top-chart :option="mixinOption" v-if="mixinOption" ></top-chart>   
    `,
    props: {
        option: {type: Object, default: () => null}, // 图表配置项
        animate: {type: Boolean, default: false},
    },

    data() {
        return {
            uuid: '', // 组件唯一标识
            myChart: null, // chart 对象
        };
    },

    computed: {
        mixinOption() {
            if (!this.option) return null;
            let {
                grid,
                yAxis,
                xAxis,
                xAxisData = [],
                series,
                legendData = [],
                tooltip = {},
                legend,
            } = this.option;

            // 直接写xAxisData(单个X轴)
            if (!xAxis && xAxisData && isArray(xAxisData) && xAxisData.length) {
                xAxis = {type: 'category', data: xAxisData};
            }
            // 重写xAxis
            if (xAxis) {
                if (isObject(xAxis)) {
                    xAxis = {type: 'category', ...xAxis};
                }
                if (isArray(xAxis)) {
                    xAxis = xAxis.map((item) => {
                        return {type: 'category', ...item};
                    });
                }
            }

            if (!yAxis) {
                yAxis = {type: 'value'};
            }

            // 多个系列
            if (!series || !isArray(series)) {
                console.error('请配置series参数,且为数组格式');
            }

            return {
                yAxis: yAxis,
                xAxis: xAxis,
                series: series,
                grid: {top: 10, left: 10, right: 10, bottom: 10, ...grid},
                legend: {
                    data: legendData,
                    textStyle: {fontSize: 10},
                    ...legend,
                },

                tooltip: {
                    trigger: 'axis',
                    textStyle: {fontSize: 10},
                    backgroundColor: 'rgba(0,0,0,0.76)',
                    borderColor: '#46ACEA',
                    axisPointer: {
                        label: {
                            backgroundColor: '#6a7985',
                            color: '#fff',
                        },
                    },
                    ...tooltip,
                },
            };
        },
    },
});


/**
 * 生成唯一标识
 * @returns {string}
 */
function uuidGenerate() {
    let d = new Date().getTime();

    if (window.performance && typeof window.performance.now === "function") {
        d += performance.now(); //use high-precision timer if available
    }

    const uuid = 'xxxxxxxx'.replace(/[xy]/g, function (c) {
        const r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });

    return 'uuid-chart' + uuid.substring(0, 8);
}

//判断是否为对象（仅为对象，不是数组也不是null）
function isObject(exp) {
    return Object.prototype.toString.call(exp) == '[object Object]';
}

//判断是否为数组（仅为数组，不是对象也不是null）
function isArray(exp) {
    return Object.prototype.toString.call(exp) == '[object Array]';
}


// 注册主题
echarts.registerTheme('theme', {
    color: THEMECOLOR,

    grid: {
        left: '10',
        right: '10',
        bottom: '10',
        top: '10',
        containLabel: true
    },

    legend: {
        inactiveColor: 'rgba(128,128,128,0.4)',
        icon: "roundRect",
        textStyle: {color: "#5BBBFF",},
        itemHeight: 5,
        itemWidth: 18,
        itemGap: 20,
        pageIconColor: '#00A592', //翻页下一页的三角按钮颜色
        pageTextStyle: {
            color: '#fff', //翻页数字颜色
        },
    },

    tooltip: {
        // textStyle: {
        //     fontSize: 10,
        //     color: "#fff",
        // },
        // backgroundColor: 'rgba(0,0,0,0.5)',
        // borderColor: "rgba(0, 0, 0, 0.5)",
        // axisPointer: {
        //     label: {
        //         backgroundColor: '#6a7985',
        //         color: '#fff',
        //     },
        // },
    },

    categoryAxis: {
        axisTick: {
            show: false
        },
        axisLine: {
            lineStyle: {
                color: "#8E8B87"
            }
        },
        axisLabel: {
            color: "#BCBFDD",
            fontFamily: "SourceHanSansCNRegular",
        }
    },

    valueAxis: {
        nameTextStyle: {
            color: "#00B9FF",
            padding: [0, 10, 0, 0]
        },
        axisTick: {show: false},
        axisLine: {show: false},
        axisLabel: {color: "#fff"},
        splitLine: {
            lineStyle: {
                color: "rgba(255,255,255,0.16)",

                type: "solid"
            }
        }
    },
});
